package jwt_hs256

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"strings"
)

type header struct {
	Alg string `json:"alg"`
	Typ string `json:"typ"`
}

var Secret string

// hmacSHA256 签名使用的 sha256 作为散列函数的hmac算法
func hmacSHA256(secret, message string) string {
	hasher := hmac.New(sha256.New, []byte(secret))
	hasher.Write([]byte(message))
	return base64.RawURLEncoding.EncodeToString(hasher.Sum(nil))
}

// GeneratorJWT 生成JWT
func GeneratorJWT(payload interface{}) (JWTStr string, err error) {
	//头base64Url编码
	header := header{
		Alg: "HS256",
		Typ: "JWT",
	}
	strHeader, err := json.Marshal(header)
	if err != nil {
		return
	}
	encodeHeader := base64.RawURLEncoding.EncodeToString(strHeader)

	//载荷base64Url编码
	strPayload, err := json.Marshal(payload)
	if err != nil {
		return
	}
	encodePayload := base64.RawURLEncoding.EncodeToString(strPayload)

	signStr := hmacSHA256(Secret, fmt.Sprintf("%s.%s", encodeHeader, encodePayload))
	JWTStr = fmt.Sprintf("%s.%s.%s", encodeHeader, encodePayload, signStr)
	return

}

// VerifyJWT 验证JWT是否被篡改
func VerifyJWT(JWTstr string) (isVerifyPassed bool, err error) {
	JWTSlice := strings.Split(JWTstr, ".")
	if len(JWTSlice) != 3 {
		return false, errors.New("JWT格式不正确")
	}

	res := hmacSHA256(Secret, fmt.Sprintf("%s.%s", JWTSlice[0], JWTSlice[1]))
	if hmac.Equal([]byte(res), []byte(JWTSlice[2])) {
		return true, nil
	} else {
		return false, nil
	}
}
